package models

import (
	"gitee.com/zhongguo168a/go-nodex/dbx"
	"gitee.com/zhongguo168a/go-nodex/dbx/mongox"
	"gitee.com/zhongguo168a/gocodes/datax/listx/constraints"
	"gitee.com/zhongguo168a/gocodes/gox/netx"
	"github.com/pkg/errors"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
)

const TableServer = "server"

func init() {
	dbx.RegisterTable(&mongox.Table{
		Name:       TableServer,
		Database:   NODE_DBNAME,
		PrimaryKey: "_id",
		Indexs: map[int]*mongo.IndexModel{
			0: {
				Keys: bson.D{
					{Key: "_id", Value: mongox.IndexSortOrderAscende},
				},
			},
		},
	})
}

func NewServerConfig() (obj *ServerConfig) {
	obj = &ServerConfig{
		MaxConn:       2147483647,
		MaxPacketSize: 4096,
		MaxMsgChanLen: 1024,
	}
	return
}

type ServerConfig struct {
	Id string `alias:"_id"`
	// 所在节点
	Node string
	// 服务器的名字，要求在节点唯一
	Name string
	// 0.0.0.0 or localnet
	Host          string // 当前服务器主机IP
	Port          string // 当前服务器主机监听端口号
	MaxPacketSize int    // 都需数据包的最大值
	MaxConn       int    // 当前服务器主机允许的最大链接个数
	MaxMsgChanLen int
	Mode          string

	//
	CertFile string
	KeyFile  string

	UpdateTime int
	CreateIime int
}

func (conf *ServerConfig) DBTable() string {
	return TableServer
}

func (conf *ServerConfig) DBIdent() string {
	return conf.Id
}

func (conf *ServerConfig) DBQuery() map[string]interface{} {
	return map[string]interface{}{
		"_id": conf.Id,
	}
}

func (conf *ServerConfig) DBObject() interface{} {
	return conf
}

func (conf *ServerConfig) DBInit() (err error) {
	return
}

func (conf *ServerConfig) RPCClient() interface{} {
	return nil
}
func (conf *ServerConfig) HttpClient() interface{} {
	return nil
}

func (conf *ServerConfig) GetIP() (ip string, err error) {
	switch conf.Host {
	case "0.0.0.0":
		ip = conf.Host
	case "localnet":
		iip, geterr := netx.GetIntranetIp()
		if geterr != nil {
			err = errors.Wrap(geterr, "get intranet ip")
			return
		}
		ip = iip.String()
	default:
		ip = conf.Host
	}
	return
}

/** ***********************************************************
  ==============================================================
  服务器
  ==============================================================
*/

func NewServerConfigListBySlice(list []*ServerConfig) (obj *ServerConfigList, err error) {
	obj = &ServerConfigList{}

	for _, val := range list {
		has := obj.List.ContainsCond(func(index int, item *ServerConfig) bool {
			return item.Name == val.Name
		})
		if has {
			err = errors.New("contains server config: " + val.Name)
			return
		}

		obj.List.Add(val)
	}
	return
}

func NewServerConfigList() (obj *ServerConfigList) {
	obj = &ServerConfigList{}
	return
}

type ServerConfigList struct {
	constraints.List[*ServerConfig]
}

func (list *ServerConfigList) DBTable() string {
	return TableServer
}

func (list *ServerConfigList) DBNewModel() dbx.IDBModel {
	r := NewServerConfig()
	list.List.Add(r)
	return r
}

func (list *ServerConfigList) DBQueryAll() map[string]interface{} {
	return map[string]interface{}{}
}

func (list *ServerConfigList) GetByName(node string, name string) *ServerConfig {
	obj, has := list.List.First(func(index int, item *ServerConfig) bool {
		return item.Name == name && item.Node == node
	})
	if has == false {
		return nil
	}
	return obj
}
